function d(id) {
	return document.getElementById(id);
}

function output(id, str) {
	d("out").innerHTML = "<span style='" + (id == "system"? "" : "color: black;") + "'>&lt;" + id + "&gt; " + str + "<span><br>" + d("out").innerHTML;
}

function newservice() {
	d("modal").getElementsByTagName("input")[0].value = "";
	d("modal").getElementsByTagName("input")[1].value = "";
	d("modal").getElementsByTagName("textarea")[0].value = "";
	d("modal").style.display = "";
}

function cancelservice() {
	d("modal").style.display = "none";
	d("modal").getElementsByTagName("input")[0].value = "";
	d("modal").getElementsByTagName("input")[1].value = "";
	d("modal").getElementsByTagName("textarea")[0].value = "";
}

function createservice() {
	var n = d("modal").getElementsByTagName("input")[0].value;
	var params = d("modal").getElementsByTagName("input")[1].value;
	var logic = d("modal").getElementsByTagName("textarea")[0].value;

	eval("function get(" + params + ") {\n"+logic + "\n}");
	
	var args = params == ""? [] : params.split(",");
	
	var newget = get;
	
	var s = {
		getName: function() {
			return n;
		},
		get: newget
	}
	
	s = parseObject(s, args);
	
	var i = updater.id+"-"+c.getID();
	
	localCache[i] = s;
	TITT.register(s, "connector", "service", i);
	

	cancelservice();
	c.updateAll();
}

var c;

var localCache = {};
var serviceCache = [];


var updater = {
	update: function(services, silent) {

		if(!silent)
			output("system", "update: " + services.length + " service" + (services.length == 1? "" : "s") + " loaded");
	
		serviceCache = [];

		for(var i = 0; i < services.length; i++) {
			if(localCache[services[i]] != null) {
				serviceCache[i] = localCache[services[i]];
			}
			else {
				serviceCache[i] = TITT.createProxy("connector", "service", services[i]);
			}
		}

		var data = [];
		
		for(var i = 0; i < serviceCache.length; i++) {
			var s = serviceCache[i];
			
			var f = s.getName();
			var uc = s.getInputs();
			var k = s.hasOutput();
			var ing = s.getPosition();
			
			data[i] = {
				service: s,
				id: f,
				inputs: uc,
				output: k,
				pos: ing
			}			
		}
		
		function createTrigger(s) {
			return function() {
//				output("system", "service triggered");
				s.output();
			}
		}
		
		CFPH.Draw.clear();
		for(var i = 0; i < data.length; i++) {
			CFPH.Draw.addService(data[i].pos[0], data[i].pos[1], data[i].id, data[i].inputs, data[i].output, data[i].service, createTrigger(data[i].service));
		}
	}
}

var old = window.onload;

function fire(f) {
	return function() {
		setTimeout(f,1000);
	}
}

var curX, curY;

window.onload = fire(function() {
	if(old)
		old();

	d("loader").style.display = "none";
	d("main").style.display = "";
	
	d("cr").onclick = createservice;
	d("cs").onclick = cancelservice;
	d("ns").onclick = newservice;
	
	d("kanvas").onmousedown = function(e) {	
		if(e.shiftKey) {
			var x = e.pageX; //not x-browser
			var y = e.pageY; //not y-browser
			
			curX = x - d("kanvas").offsetLeft - 50;
			curY = y - d("kanvas").offsetTop - 20;

			newservice();
		}
	}
	
	output("system", "loading services");
	
	var paper = Raphael("kanvas", document.body.clientWidth - 300, document.body.clientHeight- 70);

	CFPH.Draw.init(paper);
	
	CFPH.Draw.listener = {
		connectionAdded: function(from, to, argument) {
			from.connectTo(to, argument);
		},
		
		connectionRemoved: function() {
		}
	}
	
	d("out").style.height = document.body.clientHeight- 70 + "px";
	
	c = TITT.createProxy("connector");
	
	updater.id = c.getID();
	
	TITT.register(updater, "connector", "updater", updater.id);
	
	var ss = c.getAllServices();
	
	updater.update(ss, true);
	
	output("system", ss.length + " service" + (ss.length == 1? "" : "s") + " loaded");

});

function parseObject(s, args) {
	var o = hasOutput(s.get);
	var pos = [curX, curY];
	
	var buffer = {};
	var connections = [];
	
	
	function bufferFull() {
		var args = s.getInputs();
		for(var i = 0; i < args.length; i++)
			if(buffer[args[i]] == null)
				return false;
		return true;
	}
	
	s.setInputValue = function(arg, val) {
//		output("system", "got input " + arg + " = " + val);
		buffer[arg] = val;
		s.output();
	}

	s.connectTo = function(s, a) {
//		output("system", "connecting service to argument " + a);
		connections[connections.length] = {
			arg: a,
			service: s
		}
	}
	
	s.output = function() {
		if(bufferFull()) {
			var str = "";
			var args = s.getInputs();
			for(var i = 0; i < args.length; i++) {
				if(i > 0) str+=",";
				str += "buffer[args[" + i + "]]";
			}
			eval("var out = s.get(" + str + ");");
			buffer = {};
			for(var i = 0; i < connections.length; i++) {
				var c = connections[i];
				c.service.setInputValue(c.arg, out);
			}
		}
	}
	
	s.hasOutput = function() {
		return o;
	}
	
	s.getInputs = function() {
		return args;
	}
	
	s.getPosition = function() {
		return pos;
	}
	
	return s;
}

function hasOutput(f) {
	return (""+f).indexOf("return ") != -1;
}